package com.heima.article.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.article.mapper.*;
import com.heima.article.service.ApArticleService;
import com.heima.common.constants.article.ArticleConstants;
import com.heima.exception.CustomException;
import com.heima.feigns.article.ArticleFeign;
import com.heima.feigns.behavior.BehaviorFeign;
import com.heima.feigns.user.UserFeign;
import com.heima.model.article.dtos.ArticleDto;
import com.heima.model.article.dtos.ArticleHomeDto;
import com.heima.model.article.dtos.ArticleInfoDto;
import com.heima.model.article.pojos.*;
import com.heima.model.behavior.dtos.ApArticleRelationDto;
import com.heima.model.behavior.pojos.ApBehaviorEntry;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.threadlocal.AppThreadLocalUtils;
import com.heima.model.user.pojos.ApUser;
import com.heima.model.user.pojos.ApUserFollow;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class ApArticleServiceImpl extends ServiceImpl<ApArticleMapper, ApArticle> implements ApArticleService {

    @Autowired
    ApArticleConfigMapper apArticleConfigMapper;

    @Autowired
    ApArticleContentMapper apArticleContentMapper;

    @Autowired
    ApAuthorMapper apAuthorMapper;

    @Autowired
    ArticleFeign articleFeign;

    @Autowired
    UserFeign userFeign;

    @Autowired
    BehaviorFeign behaviorFeign;

    @Autowired
    ApCollectionMapper apCollectionMapper;
    /**
     * 同时保存三张表的信息
     *
     * @param articleDto
     * @return
     */
    @Override
    public ResponseResult saveApArticle(ArticleDto articleDto) {

        //1.检验参数
        if (articleDto == null) {
            throw new CustomException(AppHttpCodeEnum.PARAM_INVALID);
        }
        //2.将dto转化为article对象
        ApArticle apArticle = new ApArticle();
        BeanUtils.copyProperties(articleDto, apArticle);

        //3.根据作者名称查询作者ID
        ApAuthor author = apAuthorMapper.selectOne(Wrappers.<ApAuthor>lambdaQuery().eq(ApAuthor::getName, articleDto.getAuthorName()));
        if (author == null) {
            throw new CustomException(AppHttpCodeEnum.DATA_NOT_EXIST, "作者信息不存在");
        }
        apArticle.setAuthorId(Long.valueOf(author.getId()));

        //4.判断文章id是否存在
        if (apArticle.getId() == null) {
            //4-1 如果id为空 保存文章
            apArticle.setLikes(0);
            apArticle.setComment(0);
            apArticle.setViews(0);
            apArticle.setCollection(0);
            save(apArticle);
        } else {
            //4-2 如果id不为空,修改文章(将之前关联的文章内容和配置删除)
            updateById(apArticle);

            //将之前关联的文章配置 和 文章内容删除
            apArticleConfigMapper.delete(Wrappers.<ApArticleConfig>lambdaQuery().eq(ApArticleConfig::getArticleId, apArticle.getId()));
            apArticleContentMapper.delete(Wrappers.<ApArticleContent>lambdaQuery().eq(ApArticleContent::getArticleId, apArticle.getId()));

            //5.统一保存 配置/内容信息
            ApArticleConfig config = new ApArticleConfig();
            config.setArticleId(apArticle.getId());
            config.setIsComment(true);  //可以评论
            config.setIsForward(true);  //可以转发
            config.setIsDown(false);    //上架
            config.setIsDelete(false);  //未删除
            apArticleConfigMapper.insert(config);
            ApArticleContent content = new ApArticleContent();
            content.setArticleId(apArticle.getId());
            content.setContent(articleDto.getContent());
            apArticleContentMapper.insert(content);

            //6.返回文章id
            return ResponseResult.okResult(apArticle.getId());
            
        }
        return ResponseResult.okResult();
    }

    @Autowired
    ApArticleMapper apArticleMapper;

    @Value("${file.oss.web-site}")
    String webSite;

    /**
     * app端查询文章列表
     * @param loadtypeLoadMore
     * @param dto
     * @return
     */
    @Override
    public ResponseResult load(Short loadType, ArticleHomeDto dto) {
        //1.检查参数
        Integer size = dto.getSize();
        if(size == null || size < 1 ){
            dto.setSize(10);
        }
        if (dto.getMaxBehotTime() == null) {
            dto.setMaxBehotTime(new Date());
        }
        if (dto.getMinBehotTime() == null) {
            dto.setMinBehotTime(new Date());
        }
        if(StringUtils.isBlank(dto.getTag())){
            dto.setTag(ArticleConstants.DEFAULT_TAG);
        }
        //2.调用mapper执行查询
        List<ApArticle> apArticles = apArticleMapper.loadArticleList(dto, loadType);
        //3.封装返回值
        ResponseResult responseResult = ResponseResult.okResult(apArticles);
        responseResult.setHost(webSite);
        return responseResult;
    }

    /**
     * 根据文章id返回文章详情,返回content和config对象
     * @param dto
     * @return
     */
    @Override
    public ResponseResult loadArticleInfo(ArticleInfoDto dto) {
        //1.检查参数
        if(dto.getArticleId()==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,"文章id不能为空");
        }
        //2.根据id查询文章配置信息config (是否下架 , 是否删除)
        ApArticleConfig config = apArticleConfigMapper.selectOne(
                Wrappers.<ApArticleConfig>lambdaQuery()
                        .eq(ApArticleConfig::getArticleId,dto.getArticleId()));
            //判断,如果查询出的对象为空 或者 已下架 或者 已删除 返回报错
        if(config == null || config.getIsDelete() || config.getIsDown()){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,"文章配置信息异常");
        }
        //3.根据id查询文章内容信息content
        ApArticleContent content = apArticleContentMapper.selectOne(
                Wrappers.<ApArticleContent>lambdaQuery()
                        .eq(ApArticleContent::getArticleId,dto.getArticleId()));
        if (content == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST,"文章内容不存在");
        }
        //4.返回封装对象
        Map map = new HashMap();
        map.put("config",config);
        map.put("content",content);

        return ResponseResult.okResult(map);
    }

        @Override
        public ResponseResult loadArticleBehavior(ArticleInfoDto dto) {
            boolean isfollow=false,iscollection=false;
            //1.检查参数
            if(dto.getArticleId() == null || dto.getAuthorId() == null){
                return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
            }
            //2.查询登录用户id远程查询关注信息
            ApAuthor author = articleFeign.findById(dto.getAuthorId());
            ApUser user = AppThreadLocalUtils.getUser();
            if(author != null&&user!=null){
                ApUserFollow userFollow = userFeign.findByUserIdAndFollowId(user.getId(), author.getUserId());
                if(userFollow!=null){
                    isfollow=true;
                }
            }
            //3.远程查询行为微服务查询点赞和不喜欢的信息
            ApArticleRelationDto relationDto = new ApArticleRelationDto();
            relationDto.setArticleId(dto.getArticleId()); // 文章id
            if(user==null){
                relationDto.setEntryId(dto.getEquipmentId());
                relationDto.setType(ApBehaviorEntry.Type.EQUIPMENT.getCode());
            }else {
                relationDto.setEntryId(user.getId());
                relationDto.setType(ApBehaviorEntry.Type.USER.getCode());
            }
                //查询用户是否喜欢
            Map result = behaviorFeign.findApArticleRelation(relationDto);
            Object entryId = result.get("entryId");
            if(entryId!=null){
                //4.查询是否收藏的信息
                ApCollection apCollection = apCollectionMapper.selectOne(Wrappers.<ApCollection>lambdaQuery()
                        .eq(ApCollection::getEntryId, entryId)
                        .eq(ApCollection::getArticleId, dto.getArticleId()));
                if(apCollection!=null){
                    iscollection = true;
                }
            }
            //5.将所有信息封装成一个map集合返回前台
            result.put("isfollow",isfollow);
            result.put("iscollection",iscollection);
            return ResponseResult.okResult(result);

    }

}
